import { changeContainerStatusReq, listContainerReq } from '@/api/docker'
import bubble from '@/assets/bubble/bubble.png'
import bubbleLine from '@/assets/bubble/bubble_line.png'
import connect_button_bg from '@/assets/bubble/connect_button/activated_background.png'
import start_button from '@/assets/bubble/connect_button/activated_button.png'
import dvd_on from '@/assets/server/DVD_on_led.png'
import nameplate from '@/assets/server/nameplate_background.png'
import power_button from '@/assets/server/power_button.png'
import power_off from '@/assets/server/power_off.png'
import power_on from '@/assets/server/power_on.png'
import refresh from '@/assets/server/refresh_background.png'
import refresh_on from '@/assets/server/refresh_button_on.png'
import default_server_template from '@/assets/server/server_null.png'
import server_template from '@/assets/server/server_template.png'
import { DOCKER_NETWORK_NAME } from '@/config'
import { MyInfoDocument, MyInfoQuery, useDescribeInstancesMutation } from '@/generated/graphql'
import { Ec2Services } from '@/hooks/services/ec2Services'
import { useUserStore } from '@/stores/auth'
import { useCabinet } from '@/stores/cabinet'
import { useDockerApiPath } from '@/stores/dockerApi'
import { useCourseSessionStore } from '@/stores/useCourseStore'
import { getExtends } from '@/utils/common'
import { DLog } from '@/utils/log'
import { useClient } from '@urql/vue'
import { message, Modal } from 'ant-design-vue'
import { findIndex, last } from 'lodash-es'
import { defer, from, lastValueFrom } from 'rxjs'
import { computed, defineComponent, onMounted, reactive } from 'vue'
import { useI18n } from 'vue-i18n'
import '../views/cover.scss'

export default defineComponent({
  emits: ['showTerminal'],

  setup(props, { emit }) {
    const { t } = useI18n()
    //数据共享
    const cabinetStore = useCabinet()

    const client = useClient()

    const data = reactive<{
      containers: any
      backends?: any
      environment?: any
    }>({
      containers: [],
      backends: [],
      environment: ''
    })
    /**
     * 获取当前用户的所有容器信息
     */
    const userStore = useUserStore()
    const courseActionStore = useCourseSessionStore()

    const isPublic = computed(() => {
      return courseActionStore.type === 'PUBLIC'
    })
    const hostname = computed(() => {
      return courseActionStore.document?.extends?.PUBLIC?.backends[0]?.hostname
    })

    //获取容器信息
    const getContainers = async () => {
      const containers$ = defer(() => from(listContainerReq({ label: [`username=${userStore.user?.username}`] })))
      const containers = await lastValueFrom(containers$)

      data.containers = containers
      return containers
    }

    //刷新容器信息
    const refetchContainer = async (showMessage: boolean = true) => {
      await getContainers()
      showMessage && message.success(t('cover.refetchSuccess'))
    }

    //开启容器
    const changeContainerState = async (id: string, sign: 'start' | 'restart' | 'stop') => {
      const startContainer$ = defer(() => from(changeContainerStatusReq({ id, sign })))
      await lastValueFrom(startContainer$)
      message.success(t('cover.start_success'))
      await refetchContainer(false)
    }

    const dockerApi = useDockerApiPath()

    const { executeMutation: describeInstances } = useDescribeInstancesMutation()

    const urqlClient = useClient()
    const ec2Action = new Ec2Services(urqlClient)

    const main = async () => {
      DLog.Info('解析当前的课程信息', courseActionStore.document, courseActionStore)

      if (courseActionStore.type == 'PRIVATE') {
        // 本地环境情况
        const { backends, environment } = getExtends(courseActionStore.document)
        data.backends = backends
        data.environment = environment

        if (dockerApi.isWindows) {
          data.containers = [
            {
              Names: ['jupyter'],
              NetworkSettings: {
                Networks: {
                  [DOCKER_NETWORK_NAME]: { IPAddress: dockerApi.ip }
                }
              }
            }
          ]
        }
        !dockerApi.isWindows && (await getContainers())
      } else {
        // 线上环境情况
        const extendsData = courseActionStore.document?.extends?.PUBLIC
        data.backends = extendsData.backends
        data.environment = extendsData.environment

        // 其他还有地方也同时请求了这个接口，懒得去找了
        const me = await client.query<MyInfoQuery>(MyInfoDocument).toPromise()

        const instances = me.data?.me?.session?.instances

        if (instances) {
          const instanceIds = instances.map((x) => x.id)

          const res = await describeInstances({ data: { InstanceIds: instanceIds } })

          data.containers = res.data?.describeInstances
        }
      }
    }

    onMounted(async () => {
      await main()
    })

    /**
     * 解析容器名称
     */
    const parseContainerName = (name: string) => {
      const nameArray = name.split('-')
      DLog.Info('解析容器名称', nameArray)
      return last(nameArray)
    }

    /**
     * 获取对应的environment
     */
    const currentEnvironment = (containerName: string) => {
      if (data.environment && data.backends) {
        const containerArray = containerName.split('-')
        const _hostname = last(containerArray)

        const backendHostname = data.backends[0].hostname
        DLog.Info('获取到对应的环境', backendHostname)

        const environmentIndex = findIndex(backendHostname, (o) => o === _hostname)
        const _environment = data.environment
        return _environment[environmentIndex]
      }
      DLog.Warn('获取到环境变量有误', data)
      return []
    }

    /**
     * 获取按钮 开启关闭 状态组件
     */
    const powerStatusButton = (status: string) => {
      return status !== 'stoped' ? power_on : power_off
    }

    /**
     * 默认 主机图例 和正确主机图例获取
     */
    const serverCount = 6 //主机图例总数
    const buttonCount = computed(() => data.containers.length ?? 0)
    // 默认主机图例
    const defaultServer = computed(() => Array(serverCount - buttonCount.value).fill(0))

    return () => (
      <>
        <div class="absolute flex flex-col space-y-5 left-165 top-34">
          {data.containers &&
            data.containers.map((container: any, i: number) => (
              <div
                class="relative min-h-50.75 w-205 group"
                style={`background:url(${server_template});background-size:100% 100%;`}
              >
                <div
                  class="flex flex-col items-center w-130.25 min-h-75.25 absolute justify-start -right-125.25 invisible  group-hover:visible"
                  style={`background:url(${bubble}) no-repeat right;background-size:100% 100%;`}
                >
                  <p class="text-4xl mt-5.5 mb-3 text-fonts-400">
                    {isPublic.value ? hostname.value[i] : parseContainerName(container.Names[0])}
                  </p>
                  <img src={bubbleLine} alt="" class="ml-20 mr-5" />
                  <div class="ml-12">
                    <div class="grid grid-cols-2 gap-2 text-center mt-5.5 cursor-default">
                      <div>
                        <p class="text-xl">{t('cover.private_address')}</p>
                        <p class="text-lg text-gray-400">
                          {isPublic.value
                            ? container?.private?.PrivateIpAddress
                            : container.NetworkSettings.Networks[DOCKER_NETWORK_NAME].IPAddress}
                        </p>
                      </div>
                    </div>

                    <div class="grid grid-cols-2 gap-2 text-center cursor-pointer">
                      {isPublic.value
                        ? data.environment.map((item: any, index: number) => {
                            return (
                              <div
                                style={`background:url(${connect_button_bg})`}
                                class="w-47.5 px-2 mt-5.5 h-9.5 flex items-center justify-between"
                                onClick={() => {
                                  cabinetStore.showTerminal = true
                                  cabinetStore.instance = '' as any
                                  cabinetStore.connection = {
                                    port: item.port,
                                    path: item.path,
                                    uiLayout: item.uiLayout,
                                    ip: container.private?.PublicDnsName
                                  }
                                }}
                              >
                                <p class="text-sm">{item.uiLayout}</p>
                                <img src={start_button} alt="" />
                              </div>
                            )
                          })
                        : currentEnvironment(container.Names[0]).map((item: any, index: number) => {
                            return (
                              <div
                                style={`background:url(${connect_button_bg})`}
                                class="w-47.5 px-2 mt-5.5 h-9.5 flex items-center justify-between"
                                onClick={() => {
                                  cabinetStore.showTerminal = true
                                  cabinetStore.instance = '' as any
                                  cabinetStore.connection = {
                                    port: item.port,
                                    path: item.uiLayout,
                                    ip: container.NetworkSettings.Networks[DOCKER_NETWORK_NAME].IPAddress
                                  }
                                }}
                              >
                                <p class="text-sm">{item.uiLayout}</p>
                                <img src={start_button} alt="" />
                              </div>
                            )
                          })}
                    </div>
                    <div class="grid grid-cols-2 gap-2 text-center cursor-pointer"></div>
                  </div>
                </div>

                <img src={dvd_on} class="absolute bottom-21 right-23" />
                <div
                  class="absolute top-7 left-4 w-84.5 pb-3 h-24.5 text-5xl flex items-center justify-center text-fonts-300"
                  style={`background:url(${nameplate});background-size:100% 100%`}
                >
                  {isPublic.value ? hostname.value[i] : parseContainerName(container.Names[0])}
                </div>

                <div
                  class={[
                    'absolute top-12 right-3.5 w-21 h-13 flex items-center  px-1 cursor-pointer',
                    container.State === 'running' ? 'justify-end' : 'justify-start'
                  ]}
                  style={`background:url(${powerStatusButton(
                    isPublic.value ? container.private.State.Name : container.State
                  )});background-size:100% 100%`}
                  onClick={async () => {
                    Modal.warning({
                      title: t('cover.stop_button_tip'),
                      content: t('cover.stop_button_content'),
                      okText: 'ok',
                      onOk: async () => {
                        //启停实例
                        if (courseActionStore.type === 'PUBLIC') {
                          // 线上环境起停实例
                          if (container.private.State.Name === 'running') {
                            await ec2Action.stopInstances([container.id])
                          } else {
                            await ec2Action.startInstances([container.id])
                          }
                        } else {
                          if (container.State === 'running') {
                            await changeContainerState(container.Id, 'stop')
                          } else {
                            await changeContainerState(container.Id, 'start')
                          }
                        }
                      }
                    })
                  }}
                >
                  <img src={power_button} alt="" />
                </div>
                <div
                  class="absolute bottom-5.75 right-4 w-20 h-10.5 flex items-center justify-center cursor-pointer"
                  style={`background:url(${refresh});background-size:100% 100%`}
                  onClick={() => {
                    //刷新实例
                    refetchContainer()
                  }}
                >
                  <img src={refresh_on} alt="" />
                </div>
              </div>
            ))}

          {/*默认的机柜 渲染*/}
          {defaultServer.value.length > 0 &&
            defaultServer.value.map(() => (
              <div
                class="relative h-45.75 w-205"
                style={`background:url(${default_server_template});background-size:100% 100%`}
              />
            ))}
        </div>
      </>
    )
  }
})
